home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / network / daemons / nfs / nfs-serv.2be / nfs-serv / nfs-server-2.2beta16 / mountd.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-02-28  |  6.8 KB  |  343 lines

  1. /*
  2.  * mountd    This program handles RPC "NFS" mount requests.
  3.  *
  4.  * Usage:    [rpc.]mountd [-dhnpv] [-f authfile]
  5.  *
  6.  * Authors:    Mark A. Shand, May 1988
  7.  *        Donald J. Becker, <becker@super.org>
  8.  *        Rick Sladkey, <jrs@world.std.com>
  9.  *        Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
  10.  *        Olaf Kirch, <okir@monad.swb.de>
  11.  *
  12.  *        Copyright 1988 Mark A. Shand
  13.  *        This software maybe be used for any purpose provided
  14.  *        the above copyright notice is retained.  It is supplied
  15.  *        as is, with no warranty expressed or implied.
  16.  */
  17.  
  18.  /*
  19.  
  20.     WANT_LOG_MOUNTS guarded patch is added Aug 18, 1995 by Alex Yuriev
  21.                (alex@bach.cis.temple.edu), CIS Laboratories, 
  22.                TEMPLE UNIVERSITY, USA
  23.     
  24.     This version is ugly and can be really improved but it actually
  25.     pinpointed a couple of intruders :)
  26.                               
  27. */               
  28.  
  29.  
  30. #include "mountd.h"
  31. #include "getopt.h"
  32. #include "rpcmisc.h"
  33. #include "rmtab.h"
  34.  
  35.  
  36. static _PRO(void usage,        (FILE *, int)                );
  37.  
  38. static struct option longopts[] =
  39. {
  40.     { "debug", 0, 0, 'd' },
  41.     { "exports-file", 1, 0, 'f' },
  42.     { "help", 0, 0, 'h' },
  43.     { "allow-non-root", 0, 0, 'n' },
  44.     { "promiscous", 0, 0, 'p' },
  45.     { "re-export", 0, 0, 'r', },
  46.     { "version", 0, 0, 'v' },
  47.     { NULL, 0, 0, 0 }
  48. };
  49.  
  50. char        argbuf[MNTPATHLEN + 1];
  51. char        *auth_file = NULL;
  52. static char    *program_name;
  53. int        need_reinit = 0;
  54. int        need_flush = 0;
  55. extern char    version[];
  56.  
  57. /* The NULL request handler. */
  58. void *mountproc_null_1_svc(argp, rqstp)
  59. void *argp;
  60. struct svc_req *rqstp;
  61. {
  62.     return ((void *) &result);
  63. }
  64.  
  65. fhstatus *mountproc_mnt_1_svc(argp, rqstp)
  66. dirpath *argp;
  67. struct svc_req *rqstp;
  68. {
  69.     static fhstatus    *res;
  70.     struct stat    stbuf;
  71.     nfs_client    *cp;
  72.     nfs_mount    *mp;
  73.     char        nargbuf[MNTPATHLEN + 1];
  74. #ifdef WANT_LOG_MOUNTS
  75.     struct in_addr    addr;
  76. #endif    /* WANT_LOG_MOUNTS */
  77.  
  78.     res = (struct fhstatus *)&result;
  79.  
  80.     if (**argp == '\0') {
  81.         strcpy(argbuf, "/");
  82.     } else {
  83.         /* don't trust librpc */
  84.         strncpy(argbuf, *argp, MNTPATHLEN);
  85.         argbuf[MNTPATHLEN] = '\0';
  86.     }
  87.  
  88.     /* It is important to resolve symlinks before checking permissions. */
  89.     if (realpath(argbuf, nargbuf) == NULL) {
  90.         res->fhs_status = nfs_errno();
  91.         dprintf (D_CALL, "\tmount res = %d\n", res->fhs_status);
  92.         return (res);
  93.     }
  94.     strcpy(argbuf, nargbuf);
  95.  
  96. #ifdef WANT_LOG_MOUNTS
  97.     addr = svc_getcaller(rqstp->rq_xprt)->sin_addr;
  98.     dprintf(L_NOTICE, "NFS mount of %s attempted from %s\n",
  99.                 argbuf, inet_ntoa(addr));
  100. #endif /* WANT_LOG_MOUNTS */
  101.  
  102.     if (stat(argbuf, &stbuf) < 0) {
  103.         res->fhs_status = nfs_errno();
  104.         dprintf (D_CALL, "\tmount res = %d\n", res->fhs_status);
  105.         return (res);
  106.     }
  107.  
  108.     /* Now authenticate the intruder... */
  109.     if (((cp = auth_clnt(rqstp)) == NULL) 
  110.       || (mp = auth_path(cp, rqstp, argbuf)) == NULL
  111.       || mp->o.noaccess) {
  112.         res->fhs_status = NFSERR_ACCES;
  113. #ifdef WANT_LOG_MOUNTS
  114.         dprintf(L_WARNING, "Blocked attempt of %s to mount %s\n",
  115.                          inet_ntoa(addr), argbuf);        
  116. #endif /* WANT_LOG_MOUNTS */
  117.     } else if (!S_ISDIR(stbuf.st_mode) && !S_ISREG(stbuf.st_mode)) {
  118.         res->fhs_status = NFSERR_NOTDIR;
  119.     } else if (!re_export && nfsmounted(argbuf, &stbuf)) {
  120.         res->fhs_status = NFSERR_ACCES;
  121.     } else {
  122.         res->fhs_status = fh_create((nfs_fh *)
  123.             &(res->fhstatus_u.fhs_fhandle), argbuf);
  124.         rmtab_add_client(argbuf, rqstp);
  125. #ifdef WANT_LOG_MOUNTS
  126.         dprintf(L_NOTICE, "%s has been mounted by %s\n",
  127.                     argbuf, inet_ntoa(addr));
  128. #endif /* WANT_LOG_MOUNTS */
  129.     }
  130.     dprintf (D_CALL, "\tmount res = %d\n", res->fhs_status);
  131.     return (res);
  132. }
  133.  
  134. mountlist *mountproc_dump_1_svc(argp, rqstp)
  135. void *argp;
  136. struct svc_req *rqstp;
  137. {
  138.     return (rmtab_lst_client());
  139. }
  140.  
  141. void *mountproc_umnt_1_svc(argp, rqstp)
  142. dirpath *argp;
  143. struct svc_req *rqstp;
  144. {
  145.     rmtab_del_client(*argp, rqstp);
  146.     return ((void*) &result);
  147. }
  148.  
  149. void *mountproc_umntall_1_svc(argp, rqstp)
  150. void *argp;
  151. struct svc_req *rqstp;
  152. {
  153.     rmtab_mdel_client(rqstp);
  154.     return ((void*) &result);
  155. }
  156.  
  157. exports *mountproc_export_1_svc(argp, rqstp)
  158. void *argp;
  159. struct svc_req *rqstp;
  160. {
  161.     return (&export_list);
  162. }
  163.  
  164. exports *mountproc_exportall_1_svc(argp, rqstp)
  165. void *argp;
  166. struct svc_req *rqstp;
  167. {
  168.     return (&export_list);
  169. }
  170.  
  171. int main(argc, argv)
  172. int argc;
  173. char *argv[];
  174. {
  175.     int foreground = 0;
  176.     int c;
  177.  
  178.     rpc_init("mountd", MOUNTPROG, MOUNTVERS, mount_dispatch, 0, 0);
  179.  
  180.     program_name = argv[0];
  181.  
  182.     /* Parse the command line options and arguments. */
  183.     opterr = 0;
  184.     while ((c = getopt_long(argc, argv, "Fd:f:hnprv", longopts, NULL)) != EOF)
  185.         switch (c) {
  186.         case 'F':
  187.             foreground = 1;
  188.             break;
  189.         case 'h':
  190.             usage(stdout, 0);
  191.             break;
  192.         case 'd':
  193.             enable_logging(optarg);
  194.             break;
  195.         case 'f':
  196.             auth_file = optarg;
  197.             break;
  198.         case 'n':
  199.             allow_non_root = 1;
  200.             break;
  201.         case 'p':
  202.             promiscuous = 1;
  203.             break;
  204.         case 'r':
  205.             re_export = 1;
  206.             break;
  207.         case 'v':
  208.             printf("%s\n", version);
  209.             exit(0);
  210.         case 0:
  211.             break;
  212.         case '?':
  213.         default:
  214.             usage(stderr, 1);
  215.         }
  216.  
  217.     /* No more arguments allowed. */
  218.     if (optind != argc)
  219.         usage(stderr, 1);
  220.  
  221.     if (_rpcpmstart)
  222.         foreground = 1;
  223.  
  224.     if (!foreground) {
  225. #ifndef RPC_SVC_FG
  226.         /* We first fork off a child. */
  227.         if ((c = fork()) > 0)
  228.             exit(0);
  229.         if (c < 0) {
  230.             fprintf(stderr, "mountd: cannot fork: %s\n",
  231.                         strerror(errno));
  232.             exit(-1);
  233.         }
  234.         /* Now we remove ourselves from the foreground. */
  235.         (void) close(0);
  236.         (void) close(1);
  237.         (void) close(2);
  238. #ifdef TIOCNOTTY
  239.         if ((c = open("/dev/tty", O_RDWR)) >= 0) {
  240.             (void) ioctl(c, TIOCNOTTY, (char *) NULL);
  241.             (void) close(c);
  242.         }
  243. #else
  244.         setsid();
  245. #endif
  246. #endif /* not RPC_SVC_FG */
  247.     }
  248.  
  249.     /* Initialize logging. */
  250.     log_open("mountd", foreground);
  251.  
  252.     /* Initialize the FH module. */
  253.     fh_init();
  254.  
  255.     /* Initialize the AUTH module. */
  256.     auth_init(auth_file);
  257.  
  258.     /* Enable the LOG toggle with a signal. */
  259.     (void) signal(SIGUSR1, toggle_logging);
  260.  
  261.     /* Enable rereading of exports file */
  262.     (void) signal(SIGHUP, reinitialize);
  263.  
  264.     svc_run ();
  265.  
  266.     dprintf (L_ERROR, "Ack! Gack! svc_run returned!\n");
  267.     exit (1);
  268. }
  269.  
  270. static void usage(fp, n)
  271. FILE *fp;
  272. int n;
  273. {
  274.     fprintf(fp, "Usage: %s [-Fhnpv] [-d kind] [-f exports-file]\n",
  275.                 program_name);
  276.     fprintf(fp, "       [--debug kind] [--help] [--allow-non-root]\n");
  277.     fprintf(fp, "       [--promiscuous] [--version]\n");
  278.     fprintf(fp, "       [--exports-file=file]\n");
  279.     exit(n);
  280. }
  281.  
  282. RETSIGTYPE reinitialize(int sig)
  283. {
  284.     static volatile int    inprogress = 0;
  285.  
  286.     signal (SIGHUP, reinitialize);
  287.     if (_rpcsvcdirty) {
  288.         need_reinit = 1;
  289.         return;
  290.     }
  291.     if (inprogress++)
  292.         return;
  293.     fh_flush(1);
  294.     auth_init(NULL);
  295.     inprogress = 0;
  296.     need_reinit = 0;
  297. }
  298.  
  299. /*
  300.  * Don't look. This is an awful hack to overcome a link problem with
  301.  * auth_clnt temporarily.
  302.  */
  303. uid_t luid(uid, mp, rqstp)
  304. uid_t    uid;
  305. nfs_mount *mp;
  306. struct svc_req *rqstp;
  307. {
  308.     return -2;
  309. }
  310.  
  311. gid_t lgid(gid, mp, rqstp)
  312. gid_t    gid;
  313. nfs_mount *mp;
  314. struct svc_req *rqstp;
  315. {
  316.     return -2;
  317. }
  318.  
  319. void
  320. ugid_free_map(map)
  321. struct ugid_map *map;
  322. {
  323.     /* NOP */
  324. }
  325.  
  326. void
  327. ugid_map_uid(mp, from, to)
  328. nfs_mount *mp;
  329. uid_t    from;
  330. uid_t    to;
  331. {
  332.     /* NOP */
  333. }
  334.  
  335. void
  336. ugid_map_gid(mp, from, to)
  337. nfs_mount *mp;
  338. gid_t    from;
  339. gid_t    to;
  340. {
  341.     /* NOP */
  342. }
  343.